<template>
  <aside class="aside-wrap">
    <div class="user-info">
      <div class="bgc" />
      <img
        class="user-avatar"
        :src="
          userInfo
            ? userInfo.avatar
            : imgUrl
        "
      >
      <div class="info">
        <div class="name">
          {{ userInfo ? userInfo.username : '未登录' }}
        </div>
        <p class="title">
          {{ userInfo ? userInfo.desc : 'hello world!' }}
        </p>
      </div>
    </div>

    <AsnycCollapseCpt
      title="设置"
    >
      <template #ico>
        <el-icon>
          <Setting />
        </el-icon>
      </template>
      <div>
        <div class="item">
          <div class="switch">
            <span class="txt">黑白主题：</span>
            <el-switch
              :value="theme === 'dark'"
              :width="35"
              @change="setTheme(theme === 'dark' ? 'light' : 'dark')"
            />
          </div>
        </div>
        <div class="item">
          <div class="switch">
            <span class="txt">梅花特效：</span>
            <el-switch
              :value="showPlum"
              :width="35"
              @change="setShowPlum(!showPlum)"
            />
          </div>
        </div>
        <div class="item">
          <div class="switch">
            <span class="txt">音乐播放器：</span>
            <el-switch
              :value="showMusicAudio"
              :width="35"
              @change="setShowMusicAudio(!showMusicAudio)"
            />
          </div>
        </div>
      </div>
    </AsnycCollapseCpt>

    <AsnycCollapseCpt
      v-if="userInfo"
      title="用户信息"
    >
      <template #ico>
        <el-icon>
          <User />
        </el-icon>
      </template>
      <div>
        <div class="item">
          角色: {{ summary.roles.map((v) => v.role_name).join() }}
        </div>
        <div class="item">
          文章数: {{ summary.articlesTotal }}
        </div>
        <div class="item">
          累计发出点赞: {{ summary.sendStarsTotal }}
        </div>
        <div class="item">
          累计收到点赞: {{ summary.receiveStarsTotal }}
        </div>
        <div class="item">
          累计发出评论: {{ summary.sendCommentsTotal }}
        </div>
        <div class="item">
          累计收到回复: {{ summary.receiveCommentsTotal }}
        </div>
        <div class="item">
          qq绑定: {{ summary.qq_users && summary.qq_users.length ? '已绑定' : '未绑定' }}
        </div>
        <div class="item">
          github绑定: {{ summary.github_users && summary.github_users.length ? '已绑定' : '未绑定' }}
        </div>
      </div>
    </AsnycCollapseCpt>

    <template v-if="showCatalog">
      <div
        ref="catalogRef"
        class="catalog-ref"
      />
      <nav
        class="catalog-info"
        :class="{ fix: catalogFix }"
      >
        <div class="title">
          <el-icon><Paperclip /></el-icon>
          <b>文章目录</b>
        </div>
        <AsnycCatalogCpt :list="catalogList" />
      </nav>
    </template>

    <template v-else>
      <div>
        <AsnycCollapseCpt title="访客信息">
          <template #ico>
            <el-icon><Position /></el-icon>
          </template>
          <div>
            <template v-if="ipInfo">
              <div class="item">
                ip: {{ ipInfo.ip }}
              </div>
              <div class="item">
                location:
                {{ $filters.parseIpInfo(ipInfo) }}
              </div>
            </template>
          </div>
        </AsnycCollapseCpt>

        <AsnycCollapseCpt
          class="log-info"
          title="流量信息"
        >
          <template #ico>
            <el-icon><DataAnalysis /></el-icon>
          </template>
          <div v-loading="logLoading">
            <template v-if="historyData">
              <div class="item">
                历史总访问量: {{ historyData.visit_total }}
              </div>
              <div class="item">
                历史总访客量: {{ historyData.visitor_total }}
              </div>
            </template>
            <template v-if="dayData">
              <div class="item">
                今天总访问数: {{ dayData.visit_total }}
              </div>
              <div class="item">
                今天总访客数: {{ dayData.visitor_total }}
              </div>
            </template>
            <div
              class="refresh"
              @click="refreshLog"
            >
              <el-icon class="ico">
                <Refresh />
              </el-icon>
            </div>
          </div>
        </AsnycCollapseCpt>

        <div class="article-info">
          <div class="title">
            <div>
              <el-icon><Medal /></el-icon>
              <b>
                {{
                  sideBarArticleOrderName === 'click' ? '热门文章' : '最近更新'
                }}
              </b>
            </div>
            <span
              class="switch-btn"
              @click="switchSideBarArticleOrderName"
            >切换</span>
          </div>
          <div v-loading="switchLoading">
            <SkeletonCpt v-if="sideBarArticleList == null" />
            <div v-else-if="sideBarArticleList && sideBarArticleList?.length">
              <div
                v-for="(item, index) in sideBarArticleList"
                :key="index"
                class="item"
              >
                <div class="head-img">
                  <router-link
                    v-if="item['head_img']"
                    :to="'/article/' + item.id"
                  >
                    <img v-lazy="item['head_img']">
                  </router-link>
                  <router-link
                    v-else
                    :to="`/article/${item.id}`"
                  >
                    <div><NoHeadImgCpt /></div>
                  </router-link>
                </div>
                <div class="desc">
                  <router-link
                    :to="'/article/' + item.id"
                  >
                    #{{ item.title }}
                  </router-link>
                  <div class="info">
                    <span class="view">
                      <el-icon><View /></el-icon>
                      {{ item.click }}
                    </span>
                    <div v-if="sideBarArticleOrderName === 'click'">
                      <el-icon><Star /></el-icon>{{ item.star_total }}
                    </div>
                    <div v-else>
                      <el-icon><Calendar /></el-icon>
                      {{ $filters.convertDate(item.updated_at) }}更新
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div v-else>
              暂无文章~
            </div>
          </div>
        </div>
        <AsnycCollapseCpt
          class="tag-info"
          title="标签云"
          :open="true"
        >
          <template #ico>
            <el-icon><CollectionTag /></el-icon>
          </template>
          <div>
            <SkeletonCpt v-if="sideBarTagList == null" />
            <div v-else-if="sideBarTagList && sideBarTagList?.length">
              <el-tooltip
                v-for="item in sideBarTagList"
                :key="item.id"
                effect="dark"
                :content="'该标签下有' + item.article_total + '篇文章'"
                placement="top"
              >
                <el-tag
                  class="tag-margin"
                  :disable-transitions="false"
                  :color="item.color"
                  @click="tagClick(item.id)"
                >
                  {{ item.name }}
                </el-tag>
              </el-tooltip>
            </div>
            <div v-else>
              暂无标签~
            </div>
          </div>
        </AsnycCollapseCpt>
      </div>
    </template>
  </aside>
</template>

<script lang="ts" setup>
import { watch, nextTick, onBeforeMount, onMounted, ref } from 'vue'

import { userStore } from '@/store/user'
import { appStore } from '@/store/app'
import { logStore } from '@/store/log'
import { articleStore } from '@/store/article'
import { tagStore } from '@/store/tag'

import { storeToRefs } from 'pinia'

import { dateStartAndEnd } from '@/utils/format'

import AsnycCatalogCpt from '@/components/Catalog/index.vue'
import NoHeadImgCpt from '@/components/NoHeadImg/index.vue'
import AsnycCollapseCpt from '@/components/Collapse/index.vue'
import SkeletonCpt from '@/components/Skeleton.vue'

import { useRouter } from 'vue-router'

const router = useRouter()

const catalogRef:any = ref<HTMLElement | null>(null)

const switchLoading = ref(false)
const catalogFix = ref(false)
const logLoading = ref(false)

const { summary, userInfo } = storeToRefs(userStore())
const { ipInfo, showCatalog, theme, showPlum, showMusicAudio } = storeToRefs(appStore())
const { catalogList, sideBarArticleOrderName, sideBarArticleList } = storeToRefs(articleStore())
const { historyData, dayData } = storeToRefs(logStore())
const { sideBarTagList } = storeToRefs(tagStore())

const log = logStore()
const setTheme = appStore().setTheme
const setShowPlum = appStore().setShowPlum
const setShowMusicAudio = appStore().setShowMusicAudio

watch(() => showCatalog.value, (newVal, oldVal) => {
  newVal && cataLogObserver()
})

onBeforeMount(async () => {
  await log.getVisitorDayData(dateStartAndEnd(new Date()))
  await log.getVisitorHistoryData()
})

onMounted(() => {
  handleImgSrc()
  if (showCatalog.value) {
    cataLogObserver()
  }
  appStore().getIpInfo()
  log.getVisitorDayData(dateStartAndEnd(new Date()))
  log.getVisitorHistoryData()
})

const imgUrl = ref('')
const handleImgSrc = async () => {
  imgUrl.value = (await import('@/assets/images/admin.jpg')).default
}

const refreshLog = async () => {
  logLoading.value = true
  await log.getVisitorDayData(dateStartAndEnd(new Date()))
  await log.getVisitorHistoryData()
  logLoading.value = false
}

// 目录监听
const cataLogObserver = () => {
  nextTick(() => {
    const intersectionObserver = new IntersectionObserver((entries) => {
      entries.forEach((change) => {
        // 判断图片是否在可视范围内
        if (!change.isIntersecting) {
          catalogFix.value = true
        } else {
          catalogFix.value = false
        }
      })
    })
    intersectionObserver.observe(catalogRef.value)
  })
}

const tagClick = (id:number) => {
  router.push({ path: `/tag/${id}` })
}

const switchSideBarArticleOrderName = async () => {
  const orderName = sideBarArticleOrderName === 'click' ? 'updated_at' : 'click'
  switchLoading.value = true
  articleStore().changeSideBarArticleOrderName(orderName)
  await articleStore().getSideBarArticleList({
    nowPage: 1,
    pageSize: 5,
    orderName,
    orderBy: 'desc'
  })
  switchLoading.value = false
}
</script>

<style lang="scss" scoped>
@import '@/assets/css/constant.scss';
@import '@/assets/css/mixin.scss';

@keyframes AnimationRotat {
  0% {
      transform: rotate(0);
  }
  100% {
      transform: rotate(1turn);
  }
}
.aside-wrap {
  width: inherit;
  .user-info {
    overflow: hidden;
    padding-bottom: 10px;
    border: 1px solid $theme-color4;
    border-radius: 5px;
    background: $theme-color6;
    .bgc {
      height: 80px;
      background-image: -webkit-linear-gradient(
        43deg,
        #4158d0 0%,
        #c850c0 46%,
        #ffcc70 100%
      );
      background-image: -moz-linear-gradient(
        43deg,
        #4158d0 0%,
        #c850c0 46%,
        #ffcc70 100%
      );
      background-image: -o-linear-gradient(
        43deg,
        #4158d0 0%,
        #c850c0 46%,
        #ffcc70 100%
      );
      background-image: linear-gradient(
        43deg,
        #4158d0 0%,
        #c850c0 46%,
        #ffcc70 100%
      );
    }
    .user-avatar {
      position: relative;
      left: 50%;
      width: 80px;
      height: 80px;
      border-radius: 50%;
      transition: all 0.5s;
      transform: rotate(0) translate(-50%, -50%);
      transform-origin: 0 0;
      &:hover {
        transform: rotate(1turn) translate(-50%, -50%);
      }
    }
    .roate {
        animation: AnimationRotat 2s linear infinite;
    }
    .info {
      margin-top: -30px;
      .name {
        text-align: center;
        font-weight: bold;
      }
      .title {
        margin: 4px;
        text-align: center;
      }
    }
  }
  .article-info {
    overflow: hidden;
    margin-top: 20px;
    padding: 10px;
    border: 1px solid $theme-color4;
    border-radius: 5px;
    background: $theme-color6;
    .title {
      display: flex;
      justify-content: space-between;
      margin: 8px 0;
      .switch-btn {
        cursor: pointer;
      }
    }
    .item {
      display: flex;
      overflow: hidden;
      align-items: center;
      margin-bottom: 10px;
      height: 60px;
      &:last-child {
        margin-bottom: 0 !important;
      }
      .head-img {
        overflow: hidden;
        width: 40%;
        cursor: pointer;

        ::v-deep .no-head-img {
          font-size: 12px !important;
          &:hover {
            transform: scale(1.1);
          }
        }

        img {
          display: block;
          width: 100%;
          border-radius: 5px;
          transition: all 0.3s ease 0s;
          &:hover {
            transform: scale(1.1);
          }
        }
      }
      .desc {
        display: flex;
        flex: 1;
        flex-wrap: wrap;
        padding-left: 4px;

        justify-items: center;
        .info {
          display: flex;
          margin-top: 4px;
          width: 100%;
          font-size: 12px;
          .view {
            margin-right: 6px;
          }
        }
      }
    }
  }
  .tag-info {
    /* 覆盖默认样式，加了/deep/或者>>>反而覆盖不了？ */
    .el-tag {
      border: none;
      color: $theme-color6;
    }
    .title {
      margin: 8px 0;
    }
    .tag-margin {
      margin-right: 5px;
      margin-bottom: 5px;
      color: $theme-color6;
    }
  }
  .catalog-ref {
    transform: translateY(-50px);
  }
  .log-info {
    .refresh {
      text-align: right;
      .ico {
        cursor: pointer;
      }
    }
  }
  .catalog-info {
    overflow: hidden;
    margin-top: 20px;
    padding: 10px;
    border: 1px solid $theme-color4;
    border-radius: 5px;
    background: $theme-color6;
    &.fix {
      position: fixed;
      top: 50px;
      box-sizing: border-box;
      width: inherit;
    }
    .title {
      margin: 8px 0;
    }
  }
}
</style>
